<template>
    <div class="events">
        <div class="top">
            <span class="now-month">{{currentMonth.format("MMM, YYYY")}}</span>
            <div class="btn-wrapper">
                <div class="dropdown">
                    <i class="fif fif-calendar text-info" data-toggle="dropdown" style="cursor: pointer;"></i>
                    <ul class="dropdown-menu  animated fadeIn" role="menu" aria-labelledby="dLabel">
                        <li :key="'month' + index" v-for="(item, index) in monthRange" class="list" :class="{'active': item.value.isSame(currentMonth)}"
                            @click="changeMonth(item.value)"
                            style="border-bottom: 1px solid #eee">
                            {{item.label}}
                        </li>
                    </ul>
                </div>
            </div>
            <div class="region-wrapper">
                <select v-model="region" name="region" class="form-control">
                    <option value="">All</option>
                    <option value="japan">Japan</option>
                    <option value="thailand">Thailand</option>
                    <option value="osaka">Osaka</option>
                    <option value="tokyo">Tokyo</option>
                    <option value="kyoto">Kyoto</option>
                    <option value="others">Others</option>
                </select>
            </div>
        </div>
        <div class="content">
            <div class="left">
                <div class="pid-title item" @click="sortEvent">
                    Physical Room Id
                    <i v-if="!sort" class="fif sorting"></i>
                    <i v-if="sort === 'desc'" class="fif sorting-desc"></i>
                    <i v-if="sort === 'asc'" class="fif sorting-asc"></i>
                </div>
                <div class="item" v-for="(event, index) in events" :key="'event' + index">
                    {{event.pid + `(${event.occupancy}%)`}}
                </div>
            </div>
            <div class="right">
                <div class="top" ref="monthWrapperRef">
                    <div class="top-inner" ref="monthRef">
                        <div :key="'day' + index" class="item" v-for="(item, index) in dayRange">
                            <p class="m-0">{{item.weekEn}}</p>
                            <p class="m-0">{{item.label}}</p>
                        </div>
                    </div>
                </div>
                <div class="bottom">
                    <div  :key="'lastevent' + index"  class="line" v-for="(event, index) in events">
                        <div  :key="'calendar' + index"  class="item" :class="{active: item.hasEvent}"
                             v-for="(item, index) in event.days">
                            <div class="inner">
                                <p class="m-0" v-for="p in item.price">{{p}}</p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    //import moment from 'moment'
    import {getAllEvent} from '@/api/room'
    import {searchModel} from "@/api/model";
    import {throttle} from "@/utils";

    export default {
        name: "Events",
        data() {
            return {
                currentMonth: '',
                dayRange: [],
                allEvents: [],
                events: [],
                priceData: [],
                sort: '',
                region: 'thailand'
            }
        },
        activated() {
            // 让表头固定在顶部
            let scrollFn = throttle( () => {
                if (!this.isElementInViewport(this.$refs.monthWrapperRef)) {
                    this.$refs.monthRef.style = `z-index :100;position: fixed;top:60px;width: ${this.$refs.monthWrapperRef.clientWidth}px`
                } else {
                    this.$refs.monthRef.style = 'position: relative;'
                }
            }, 200)

            $(document).bind('scroll', () => {
                scrollFn()
            })
        },
        deactivated() {
            $(document).unbind('scroll')
        },
        created() {
            let now = moment()
            this.weekArr = ["Sun.", "Mon.", "Tues.", "Wed.", "Thur.", "Fri", "Sat."]
            this.currentMonth = now
            this.monthRange = []
            for (let i = -6; i <= 6; i++) {
                let current = moment(now).add(i, 'months')
                this.monthRange.push(
                    {label: current.format('YYYY-MM'), value: current}
                )
            }
            this.fetch()
            this.fetchPrice()
        },
        methods: {
            fetch() {
                this._getDayRange(this.currentMonth)
                getAllEvent(this.region).then(res => {
                    this.allEvents = res.data.exportEvents
                    this._getThisMonthEvents(this.currentMonth)
                })
            },
            fetchPrice() {
                let page = 1;
                let pageSize = 300;
                let start = this.dayRange[0].value
                let end =  this.dayRange[this.dayRange.length - 1].value
                searchModel("PriceCalendar", {
                    "search_keys": {date__gte: start, date__lte: end},
                    "page_size": pageSize,
                    "page": page,
                }).then(res => {
                    this.priceData = this.priceData.concat(res.data.list)
                    this.setAllEventPrice(res.data.list)
                    let range = res.data.page.range
                    while (page < range) {
                        page += 1
                        searchModel("PriceCalendar", {
                            "search_keys": {date__gte: start, date__lte: end},
                            "page_size": pageSize,
                            "page": page,
                        }).then( res => {
                            this.priceData = this.priceData.concat(res.data.list)
                            this.setAllEventPrice(res.data.list)
                        })
                    }
                })
            },
            setAllEventPrice(arr) {
                for (let i=0; i<this.events.length; i++) {
                    for (let j=0; j<this.events[i].days.length; j++) {
                        if (!this.events[i].days[j].price.length)
                            this.events[i].days[j].price = this.setPrice(this.events[i].id, this.events[i].days[j].date, arr)
                    }
                }
            },
            setPrice(pid, date, arr) {
                let price = []
                for (let i=0; i<arr.length; i++) {
                    if (arr[i].physical_room === pid && arr[i].date === date) {
                        price = [arr[i].price, arr[i].currency]
                        break;
                    }
                }
                return price
            },
            sortEvent() {
                this.sort = this.sort === 'desc' ? 'asc' : 'desc'

                this.events.sort((a, b) => {
                    return this.sort === 'asc' ? a.occupancy - b.occupancy : b.occupancy - a.occupancy
                })
            },
            changeMonth(newMonth) {
                this.currentMonth = moment(newMonth)
                this._getDayRange(newMonth)
                this._getThisMonthEvents(newMonth)
                this.fetchPrice()
            },
            isElementInViewport(el, offset = 0) {
                const box = el.getBoundingClientRect(), top = (box.top >= 0), left = (box.left >= 0),
                    bottom = (box.bottom <= (window.innerHeight || document.documentElement.clientHeight) + offset),
                    right = (box.right <= (window.innerWidth || document.documentElement.clientWidth) + offset);
                return (top && left && bottom && right);
            },
            _getDayRange(current) {
                this.dayRange = []
                let daysInMonth = current.daysInMonth()
                let firstDayInMonth = moment([current.year(), current.month(), 1])
                for (let i = 0; i < daysInMonth; i++) {
                    let now =  i !== 0 ? moment(firstDayInMonth.add(1, 'days')) : firstDayInMonth
                    this.dayRange.push({
                        label: (i + 1) <= 9 ? '0' + (i + 1) : i + 1,
                        value: now.format('YYYY-MM-DD'),
                        weekEn: this.weekArr[now.day()]
                    })
                }
            },
            _getThisMonthEvents(current) {
                this.events = []
                let daysInMonth = current.daysInMonth()
                let firstDayInMonth = moment([current.year(), current.month(), 1]).format('YYYY-MM-DD')
                let lastDayInMonth = moment([current.year(), current.month(), daysInMonth]).format('YYYY-MM-DD')
                let data = this.allEvents
                let events = {}
                data.forEach(item => {
                    let pid = item.pid
                    events[pid] = {calendar: []}
                    events[pid].id = item.id
                    item.events.forEach(event => {
                        if (event.start >= firstDayInMonth && event.end <= lastDayInMonth) {
                            events[pid].calendar = events[pid].calendar.concat(this._getActiveDate(event.start, event.end))
                        } else if (event.start >= firstDayInMonth && event.start < lastDayInMonth) {
                            events[pid].calendar = events[pid].calendar.concat(this._getActiveDate(event.start, lastDayInMonth))
                        } else if (event.end <= lastDayInMonth && event.end > firstDayInMonth) {
                            events[pid].calendar = events[pid].calendar.concat(this._getActiveDate(firstDayInMonth, event.end))
                        } else if (event.start === lastDayInMonth) {
                            events[pid].calendar.push(lastDayInMonth)
                        } else if (event.start < firstDayInMonth && event.end > lastDayInMonth) {
                            events[pid].calendar = events[pid].calendar.concat(this._getActiveDate(firstDayInMonth, lastDayInMonth))
                            events[pid].calendar.push(lastDayInMonth)
                        }
                    })
                })

                let tmp = []
                for (let key in events) {
                    let days = []
                    this.dayRange.forEach(item => {
                        days.push({
                            date: item.value,
                            hasEvent: events[key].calendar.indexOf(item.value) !== -1,
                            price: this.setPrice(events[key].id, item.value, this.priceData)
                        })
                    })
                    tmp.push({
                        days: days,
                        id: events[key].id,
                        pid: key,
                        occupancy: (parseFloat(events[key].calendar.length / daysInMonth) * 100).toFixed(1)
                    })

                }

                if (this.sort) {
                    tmp.sort((a, b) => {
                        return this.sort === 'asc' ? a.occupancy - b.occupancy : b.occupancy - a.occupancy
                    })
                }

               this.events = tmp
            },
            _getActiveDate(start, end) {
                let diff = moment(end).diff(moment(start), 'days')
                let calendar = []
                for (let i = 0; i < diff; i++) {
                    calendar.push(moment(start).add(i, 'days').format('YYYY-MM-DD'))
                }
                return calendar
            }
        },
        watch:{
            region() {
                this.fetch()
            }
        }
    }
</script>

<style scoped lang="stylus">
    .events
        .sorting::after
            font-family: 'fif', serif;
            opacity: 0.4;
            content: "\e796";
            cursor: pointer;

        .sorting-desc::after
            font-family: 'fif', serif;
            opacity: 0.8;
            content: "\e790";
            cursor: pointer;

        .sorting-asc::after
            font-family: 'fif', serif;
            opacity: 0.8;
            content: "\e795";
            cursor: pointer;
        .fixed
            position: fixed;
        .list
            padding: 4px 10px;
            cursor: pointer;
            &:hover
                background-color: #dedede;
            &.active
                background-color #1e88e5;
                color: #fff;
        .top
            margin-bottom: 15px;
            .now-month
                font-weight: bold;
                font-size: 20px;
            .btn-wrapper
                display :inline-block;
            .region-wrapper
                float :right;
        .content
            display: flex;
            .left
                width: 150px;
                min-width: 130px;
                margin-right: 4px;
                .pid-title
                    cursor: pointer;
                .item
                    box-sizing: border-box;
                    height: 40px;
                    padding: 10px 4px;
                    background-color: #fff;
                    &:first-child
                        background-color: #6b7f7d;
                        color: #fff;
            .right
                flex: 1;
                overflow-x: auto;
                .top
                    height: 40px;
                    margin-bottom: 0;
                    .top-inner
                        height: 40px;
                        display: flex;
                        margin-bottom: 0;
                        .item
                            flex: 1;
                            padding: 0 4px;
                            background-color: #6b7f7d;
                            color: #fff;
                            display: inline-block;
                            text-align: center;
                .bottom
                    .line
                        height: 40px;
                        display: flex;
                        .item
                            flex: 1;
                            box-sizing: border-box;
                            height: 40px;
                            min-width: 24.4px;
                            padding: 2px;
                            .inner
                                width: 100%;
                                height: 100%;
                                background-color: #fff;
                                font-size :12px;
                                text-align :center;
                                line-height :0;
                                >p
                                    transform :scale(0.8)
                            &.active
                                .inner
                                    background-color: #9ad062;
</style>